package com.ruoyi.basebill.service.impl.billIssue.util;

import com.ruoyi.basebill.domain.*;
import com.ruoyi.basebill.mapper.billIssue.BillIssueMapper;
import com.ruoyi.basedata.domain.WfzBaseunit;
import com.ruoyi.basedata.domain.WfzPerson;
import com.ruoyi.basedata.service.impl.WfzBaseunitServiceImpl;
import com.ruoyi.basedata.service.impl.WfzPersonServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Component
public class BillIssueUtil {


    //组织成本中心服务层实现类

    @Autowired
    private  WfzBaseunitServiceImpl wfzBaseunitService;


    //员工档案服务层实现类

    @Autowired
    private WfzPersonServiceImpl wfzPersonService;


    //单据下发通用类dao层接口

    @Autowired
    private  BillIssueMapper billIssueMapper;


    /**
     * 其他单据获取结算方式---（除社保公积金）
     * @param gyNumber 盖亚组织编码
     * @param costnumber 分录的成本中心编码
     * @return 结算方式
     */
    public String Jsfs(String gyNumber,String costnumber){
        String jsfs = null;
        //准备一个组织成本中心对象用于获取单据头组织信息
        WfzBaseunit wfzBaseunit1 = new WfzBaseunit();
        //准备一个组织成本中心对象用于获取分录成本中心信息
        WfzBaseunit wfzBaseunit2 = new WfzBaseunit();

        wfzBaseunit1.setFgynumber(gyNumber);
        List<WfzBaseunit> wfzBaseunits1 = wfzBaseunitService.selectWfzBaseunitList(wfzBaseunit1);
        if(wfzBaseunits1.size() > 0){
            wfzBaseunit1 = wfzBaseunits1.get(0);
        }else {

        }

        wfzBaseunit2.setFgynumber(costnumber);
        List<WfzBaseunit> wfzBaseunits2 = wfzBaseunitService.selectWfzBaseunitList(wfzBaseunit2);
        if (wfzBaseunits2.size() > 0){
            wfzBaseunit2 = wfzBaseunits2.get(0);
        }

        //开始判断
        //组织间结算方式：
        //首先判断如果单据组织为实业，成本中心编码左类似1.10.100.91；如果单据组织为餐饮，成本中心编码左类似1.20.100.91
        //条件成立则是： “同组织下合并纳税成本中心”
        //条件不成立则进入另一个分支进行判断
        //判断成本中心所属二级组织与单据组织相同
        //如果相同则是  “同组织下成本中心”
        //如果不同则进入另一个分支进行判断
        //判断成本中心是否和单据组织的所属一级组织相同
        //如果相同则进入下一步判断
        //如果不同则是  “非同组织”
        //判断成本中心是否与单据的所属二级组织相同
        //如果不同则是  “同组织下是二级组织”

        //单据头组织编码
        String fnumber1 = wfzBaseunit1.getFnumber();
        //单据头组织所属一级组织
        String fonecompany = wfzBaseunit1.getFonecompany();
        //单据头组织所属二级组织
        String ftwocompany = wfzBaseunit1.getFtwocompany();
        //分录成本中心编码
        String fnumber2 = wfzBaseunit2.getFnumber();
        //分录成本中心所属二级组织
        String ftwocompany1 = wfzBaseunit2.getFtwocompany();

        //开始判断
        boolean result1 = "1.10.100".equals(fnumber1);//单据组织等于实业
        boolean result2 = "1.10.100.91".equals(fnumber2.substring(0,11));//成本中心编码左类似
        boolean result3 = "1.20.100".equals(fnumber1);//单据组织等于餐饮
        boolean result4 = "1.20.100.91".equals(fnumber2.substring(0,11));//成本中心编码左类似
        if ((result1 && result2) || (result3 && result4)){
            jsfs = "同组织下合并纳税成本中心";
        }else if (ftwocompany1.equals(fnumber1)){
            jsfs = "同组织下成本中心";
        }else {
            if (fonecompany.equals(fnumber2)){
                if (!ftwocompany.equals(fnumber2)){
                    jsfs = "同组织下是二级组织";
                }
            }else {
                jsfs = "非同组织";
            }
        }
        return jsfs;
    }


    /**
     * 传入单据类型、单据头组织编码、人员编码获取结算方式
     * @param jsfsType 单据类型（单据的类对象）
     * @param gyNumber 单据头的盖亚组织编码
     * @param personNumber 分录中的人员编码
     * @return
     */
    public String Jsfs(Jsfs jsfsType,String gyNumber, String personNumber){
        String jsfs = null;
        //准备一个组织成本中心对象用于获取单据头组织信息
        WfzBaseunit wfzBaseunit = new WfzBaseunit();
        //准备一个员工档案对象，存储分录中的员工编号
        WfzPerson wfzPerson = new WfzPerson();

        wfzBaseunit.setFgynumber(gyNumber);
        List<WfzBaseunit> wfzBaseunits = wfzBaseunitService.selectWfzBaseunitList(wfzBaseunit);
        if (wfzBaseunits.size() == 0){

        }
        wfzBaseunit = wfzBaseunits.get(0);

        wfzPerson.setFnumber(personNumber);
        List<WfzPerson> wfzPeople = wfzPersonService.selectWfzPersonList(wfzPerson);
        wfzPerson = wfzPeople.get(0);

        //单据头组织编码
        String fnumber = wfzBaseunit.getFnumber();
        //分录成本中心编码
        String fsscost = wfzPerson.getFsscost();
        //单据头组织所属一级组织
        String fonecompany = wfzBaseunit.getFonecompany();
        //单据头组织所属二级组织
        String ftwocompany = wfzBaseunit.getFtwocompany();

        // 开始判断

        // 判断逻辑：
        // 首先判断如果单据组织为实业，成本中心编码左类似1.10.100.91；如果单据组织为餐饮，成本中心编码左类似1.20.100.91
        // 条件成立则是：“同组织下合并纳税成本中心”
        // 如果不同则进入另一个分支进行判断
        // 判断社保或公积金单据
        // 判断成本中心所属社保、公积金单位（承担公司）与单据组织相同
        // 如果相同则是  “同组织下成本中心”
        // 如果不同则进入另一个分支进行判断
        // 判断人员所属社保、公积金单位（承担公司）与单据组织所属的一级组织是否相同
        // 如果相同则进入下一步判断
        // 如果不同则是  “非同组织”
        // 判断人员所属社保、公积金单位（承担公司）与单据组织的所属二级组织是否相同
        // 如果不同则是  “同组织下是二级组织”

        //判断是否社保相关单据获取结算方式
        boolean result1 = Jsfs.SB.equals(jsfsType);
        //判断是否公积金相关单据获取结算方式
        boolean result2 = Jsfs.GJJ.equals(jsfsType);

        boolean result3 = "1.10.100".equals(fnumber);//单据组织等于实业
        boolean result4 = "1.10.100.91".equals(fsscost.substring(0,11));//成本中心编码左类似
        boolean result5 = "2.10.100".equals(fnumber);//单据组织等于餐饮
        boolean result6 = "1.20.100.91".equals(fsscost.substring(0,11));//成本中心编码左类似

        if ((result3 && result4) || (result5 && result6)){
            jsfs = "同组织下合并纳税成本中心";
        }else {
            //社保判断
            if (result1){
                //获取社保承担公司
                String fsbcdgs = wfzPerson.getFsbcdgs();
                if (fnumber.equals(fnumber)){
                    jsfs = "同组织下成本中心";
                }else {
                    if (fonecompany.equals(fsbcdgs)){
                        if (!ftwocompany.equals(fsbcdgs)){
                            jsfs = "同组织下是二级组织";
                        }
                    }else {
                        jsfs = "非同组织";
                    }
                }
            }//公积金判断
            else if (result2){
                //获取公积金承担公司
                String fgjjcdgs = wfzPerson.getFgjjcdgs();
                if (fgjjcdgs.equals(fnumber)){
                    jsfs = "同组织下成本中心";
                }else {
                    if (fonecompany.equals(fgjjcdgs)){
                        if (!ftwocompany.equals(fgjjcdgs)){
                            jsfs = "同组织下是二级组织";
                        }
                    }else {
                        jsfs = "非同组织";
                    }
                }
            }
        }

        return jsfs;
    }



    /**
     * 获取成本中心属性
     * @param gyNumber 传入的分录中的成本中心编码
     * @return 成本中心属性
     */
    public String costType(String gyNumber){
        WfzBaseunit wfzBaseunit = new WfzBaseunit();
        wfzBaseunit.setFgynumber(gyNumber);
        List<WfzBaseunit> wfzBaseunits = wfzBaseunitService.selectWfzBaseunitList(wfzBaseunit);
        wfzBaseunit = wfzBaseunits.get(0);
        return wfzBaseunit.getFcosttype();
    }


    public WfzPerson getPerson(String personNumber){
        WfzPerson wfzPerson = new WfzPerson();
        WfzPerson person = new WfzPerson();
        wfzPerson.setFnumber(personNumber);
        List<WfzPerson> wfzPeople = wfzPersonService.selectWfzPersonList(wfzPerson);
        if (wfzPeople.size() == 0){
            person = wfzPeople.get(0);
        }
        return person;

    }

    /**
     * 获取成本中心编码
     * @param gyNumber 传入的盖亚组织编码
     * @return 成本中心编码
     */
    public  String costNumber(String gyNumber){
        WfzBaseunit wfzBaseunit = new WfzBaseunit();
        wfzBaseunit.setFgynumber(gyNumber);
        List<WfzBaseunit> wfzBaseunits = wfzBaseunitService.selectWfzBaseunitList(wfzBaseunit);
        wfzBaseunit = wfzBaseunits.get(0);
        return wfzBaseunit.getFnumber();
    }

    /**
     * 根据传入的盖亚组织编码查找对应的成本中心中的《是否当月发放社保公积金》字段
     * @param gyNumber 盖亚组织编码
     * @return 是否当月发放社保公积金
     */
    public Long getIsdysb(String gyNumber){
        WfzBaseunit wfzBaseunit = new WfzBaseunit();
        wfzBaseunit.setFgynumber(gyNumber);
        List<WfzBaseunit> wfzBaseunits = wfzBaseunitService.selectWfzBaseunitList(wfzBaseunit);
        wfzBaseunit = wfzBaseunits.get(0);
        return Long.valueOf(wfzBaseunit.getFisdysb());
    }

    public String getPzz(String gyNumber){
        WfzBaseunit wfzBaseunit = new WfzBaseunit();
        wfzBaseunit.setFgynumber(gyNumber);
        List<WfzBaseunit> wfzBaseunits = wfzBaseunitService.selectWfzBaseunitList(wfzBaseunit);
        wfzBaseunit = wfzBaseunits.get(0);
        return wfzBaseunit.getFpzz();
    }



    /**
     * 传入单据对象，为单据编码赋值
     * @param o 传入的单据对象
     */
    public void setBillNumber(Object o){
        //单据编号
        String number;
        //准备一个集合用来存储单据表名
        HashMap<String,String> tableName = new HashMap<>();
        tableName.put("社保缴纳","t_wfz_sbjr");
        tableName.put("社保分摊","t_wfz_sbft");
        tableName.put("社保计提","t_wfz_sbjt");
        tableName.put("公积金缴纳","t_wfz_gjjjr");
        tableName.put("公积金分摊","t_wfz_gjjft");
        tableName.put("公积金计提","t_wfz_gjjjt");
        tableName.put("年终奖冲回","t_wfz_nzjch");
        tableName.put("年终奖发放","t_wfz_nzjff");
        tableName.put("年终奖分摊","t_wfz_nzjft");
        tableName.put("工资计提","t_wfz_gzjt");
        tableName.put("工资发放","t_wfz_gzff");
        tableName.put("工资分摊","t_wfz_gzft");


        Class<?> Class = o.getClass();
        if (Class == WfzSbjr.class){
            String s = tableName.get("社保缴纳");
            //传入单据标识和数据库中最新的一条单据编号生成单据编号
            number = createBillNumber(s);
            ((WfzSbjr) o).setFnumber(number);
        } else if (Class == WfzSbft.class) {
            String s = tableName.get("社保分摊");
            //传入单据标识和数据库中最新的一条单据编号生成单据编号
            number = createBillNumber(s);
            ((WfzSbft) o).setFnumber(number);
        } else if (Class == WfzSbjt.class) {
            String s = tableName.get("社保计提");
            //传入单据标识和数据库中最新的一条单据编号生成单据编号
            number = createBillNumber(s);
            ((WfzSbjt) o).setFnumber(number);
        }else if (Class == WfzGjjjr.class){
            String s = tableName.get("公积金缴纳");
            //传入单据标识和数据库中最新的一条单据编号生成单据编号
            number = createBillNumber(s);
            ((WfzGjjjr) o).setFnumber(number);
        } else if (Class == WfzGjjft.class) {
            String s = tableName.get("公积金分摊");
            //传入单据标识和数据库中最新的一条单据编号生成单据编号
            number = createBillNumber(s);
            ((WfzGjjft) o).setFnumber(number);
        } else if (Class == WfzGjjjt.class) {
            String s = tableName.get("公积金计提");
            //传入单据标识和数据库中最新的一条单据编号生成单据编号
            number = createBillNumber(s);
            ((WfzGjjjt) o).setFnumber(number);
        }else if (Class == WfzNzjch.class){
            String s = tableName.get("年终奖冲回");
            //传入单据标识和数据库中最新的一条单据编号生成单据编号
            number = createBillNumber(s);
            ((WfzNzjch) o).setFnumber(number);
        } else if (Class == WfzNzjff.class) {
            String s = tableName.get("年终奖发放");
            //传入单据标识和数据库中最新的一条单据编号生成单据编号
            number = createBillNumber(s);
            ((WfzNzjff) o).setFnumber(number);
        } else if (Class == WfzNzjft.class) {
            String s = tableName.get("年终奖分摊");
            //传入单据标识和数据库中最新的一条单据编号生成单据编号
            number = createBillNumber(s);
            ((WfzNzjft) o).setFnumber(number);
        }else if (Class == WfzGzjt.class){
            String s = tableName.get("工资计提");
            //传入单据标识和数据库中最新的一条单据编号生成单据编号
            number = createBillNumber(s);
            ((WfzGzjt) o).setFnumber(number);
        } else if (Class == WfzGzff.class) {
            String s = tableName.get("工资发放");
            //传入单据标识和数据库中最新的一条单据编号生成单据编号
            number = createBillNumber(s);
            ((WfzGzff) o).setFnumber(number);
        } else if (Class == WfzGzft.class) {
            String s = tableName.get("工资分摊");
            //传入单据标识和数据库中最新的一条单据编号生成单据编号
            number = createBillNumber(s);
            ((WfzGzft) o).setFnumber(number);
        }else {

        }
    }


    /**
     *  根据传入的表名，生成对应的单据的编码
     * @param tableName
     * @return
     */
    private String createBillNumber(String tableName){
        //获取指定单据的最新一条记录的编码
        String formerBillNumber = billIssueMapper.getNewNumber(tableName);
        //截取表名中的最后一段表名
        String[] s1 = tableName.split("_");
        String billLogotype = s1[s1.length - 1];
        //最终的单据编号
        String commentNumber = "";
        //时间字符串产生方式
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        //组合流水号前一部分
        String billNumberPfix = format.format(new Date());
        //判断数据库中是否存在数据
        if (formerBillNumber != null && formerBillNumber.contains(billNumberPfix)){
            //从单据编号中截取后四位
            String billNumberEnd = formerBillNumber.substring(formerBillNumber.length() - 4);
            int endNumber = Integer.parseInt(billNumberEnd);
            int tempNumber = 10000 + endNumber + 1;
            //将首位的1去掉之后，拼接成流水号
            commentNumber =billLogotype.toUpperCase() + billNumberPfix + BillIssueUtil.subStr("" + tempNumber,1);
        }else {
            //当数据库中没有数据时
            commentNumber =billLogotype.toUpperCase() + billNumberPfix + "0001";
        }

        return commentNumber;
    }


    /**
     * 去除字符串首位的方法
     * @param str 传入的字符串
     * @param start 截取开始的起始位置
     * @return 截取完毕的数据
     */
    public static String subStr(String str,int start){

        if (str == null || str.equals("") || str.length() == 0)
            return "";
        if (start < str.length()){
            return str.substring(start);
        }else {
            return "";
        }
    }

}

